﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Ext.h".
//-------------------------------------------------------------------

#ifndef _UXS_THREAD_OPERATION_H
#define _UXS_THREAD_OPERATION_H

#pragma once

#include "../OS.h"

namespace UX_STL
{
namespace UXTypesExt
{
	using namespace UXTypesExt;

	
	//
	// Thread Operation Interface
	//

	class IThreadOp
	{
	public:
		virtual void Do() = 0;
	};



	//
	// Thread Operation with Counter interface
	//

	class IThreadOpC : public IThreadOp
	{
	public:
		virtual void SetCounter(int) = 0;
		virtual void Free() = 0;
	};



	//
	// Universal Operation
	//

	class UX_EXPORT CUniThreadOp : public IThreadOp
	{
	public:
		typedef function< void >		function_t;

	protected:
		function_t	_func;

	public:
		CUniThreadOp (const function_t &func): _func(func)
		{}

		virtual ~CUniThreadOp ()
		{}

		virtual void Do ()
		{
			_func.SafeCall();

			delete this;
		}
	};



	//
	// Universal Operation with synchronization
	//

	class UX_EXPORT CUniThreadOpSync : public CUniThreadOp
	{
	protected:
		SyncEvent		_sESync;

	public:
		CUniThreadOpSync (const function_t &func):
			CUniThreadOp(func), _sESync( SyncEvent::AUTO_RESET )
		{}

		~CUniThreadOpSync ()
		{}

		virtual void Do ()
		{
			_func.SafeCall();

			_sESync.Signal();
		}

		bool Sync (uint uTime = -1)
		{
			return _sESync.Wait( uTime );
		}

		void Free ()
		{
			delete this;
		}
	};



	//
	// Universal Operation with Counter
	//

	class UX_EXPORT CUniThreadOpC : public IThreadOpC
	{
	public:
		typedef function< void >	function_t;

	protected:
		function_t		_func;
		atomic_int32	_sCounter;

	public:
		CUniThreadOpC (const function_t &func): _func(func), _sCounter(0)
		{}

		virtual ~CUniThreadOpC ()
		{}

		virtual void SetCounter (int i)
		{
			_sCounter = i;
		}

		virtual void Free ()
		{
			delete this;
		}

		virtual void Do ()
		{
			_func.SafeCall();

			if ( --_sCounter <= 0 )
				delete this;
		}
	};



	//
	// Universal Operation with Counter & with sync
	//

	class UX_EXPORT CUniThreadOpCS : public CUniThreadOpC
	{
	public:
		SyncEvent	_sEvent;

	public:
		CUniThreadOpCS (const function_t &func):
			CUniThreadOpC(func), _sEvent( SyncEvent::AUTO_RESET )
		{}

		~CUniThreadOpCS ()
		{}

		virtual void Do ()
		{
			_func.SafeCall();

			if ( --_sCounter <= 0 )
				_sEvent.Signal();
		}

		bool Sync (uint uTime = -1)
		{
			return _sEvent.Wait( uTime );
		}
	};

//-------------------------------------------------------------------

}	// UXTypesExt
}	// UX_STL

#endif	// _UXS_THREAD_OPERATION_H